package org.keyroy.map_editor.ui.components;

import java.awt.Color;
import java.awt.Graphics;
import java.awt.Point;
import java.awt.Rectangle;
import java.awt.event.ComponentAdapter;
import java.awt.event.ComponentEvent;
import java.awt.event.InputEvent;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.util.ArrayList;
import java.util.List;

import javax.swing.JComponent;

import org.keyroy.map_editor.ui.components.SmallMapComponent.SmallMapListener;

public class MapComponent extends JComponent {
	private static final long serialVersionUID = 1L;
	public static final Color COLOR_SELECTED_AREA = new Color(0xff3366cc, true);
	public static final Color COLOR_TEXT_AREA = new Color(0x99000000, true);
	public static final Color COLOR_SHADOW = new Color(0x77000000, true);

	public static final int POINTER_STATE_EDIT_FLOOR = 0;
	public static final int POINTER_STATE_EDIT_ITEM = 1;

	private List<Rectangle> selectedRectangles = new ArrayList<Rectangle>();

	private Rectangle window;
	private int pointerState;
	private int keyCode, keyModifiersEx;
	private Point _pointer = new Point();
	private Point _mapPointer = new Point();

	private Rectangle _rectangle = new Rectangle();
	private Rectangle _drawRectangle = new Rectangle();

	private int editID;

	private MapComponent() {
		window = new Rectangle();

		addComponentListener(new ComponentAdapter() {
			@Override
			public void componentResized(ComponentEvent e) {
				requestFocus();
				window.setSize(getWidth(), getHeight());
				callScreenAreaChangeListener();
			}
		});
		addKeyListener(new KeyAdapter() {
			@Override
			public void keyPressed(KeyEvent e) {
			}

			@Override
			public void keyReleased(KeyEvent e) {
				keyCode = 0;
				keyModifiersEx = 0;
			}
		});
		PointerListener pointerListener = new PointerListener();
		addMouseListener(pointerListener);
		addMouseMotionListener(pointerListener);
	}

	public void deleteSeletedItem(int id) {
		flushMap();
		callMapElemenetChangeListener();
	}

	@Override
	public void paint(Graphics g) {
	}

	private final void drawParam(Graphics g) {
		int height = g.getFontMetrics().getHeight();
		g.setColor(COLOR_TEXT_AREA);
		g.fillRect(0, getHeight() - height, getWidth(), height);
		g.setColor(Color.white);
		StringBuffer stringBuffer = new StringBuffer();
		stringBuffer.append("x = ").append(_mapPointer.x).append("    ");
		stringBuffer.append("y = ").append(_mapPointer.y).append("    ");

		if (isControlKeyDown()) {
			stringBuffer.append("ctrl");
		}

		g.drawString(stringBuffer.toString(), 5, getHeight() - 3);

	}

	private final void drawSelectArea(Graphics g) {
	}

	private Thread repaintThread;
	private int repaintCount;

	private final void flushMap() {
		repaintCount++;
		if (repaintThread == null || repaintThread.isAlive() == false) {
			repaintThread = new Thread(new Runnable() {
				@Override
				public void run() {
					while (repaintCount > 0) {
						repaint();
						repaintCount--;
						try {
							Thread.sleep(10);
						} catch (Exception e) {
						}
					}
				}
			});
			repaintThread.start();
		}
	}

	private class PointerListener extends MouseAdapter {
		private Rectangle _tempRectangle = new Rectangle();
		private Rectangle _selectRectangle = new Rectangle();

		@Override
		public void mouseClicked(MouseEvent e) {
			if (isLeftButton(e)) {
			} else if (isRightButton(e)) {
				if (isEditFloor()) {
					cleanSelectedFloorArea();
				} else if (isEditItem()) {
					cleanSelectedItem();
				}
			}
		}

		@Override
		public void mousePressed(MouseEvent e) {
		}

		@Override
		public void mouseDragged(MouseEvent e) {
		}

		@Override
		public void mouseReleased(MouseEvent e) {
			cleanSelectRectangle();
			flushMap();
		}

		@Override
		public void mouseMoved(MouseEvent e) {
		}

		private void initPointer(MouseEvent e) {
		}

		private void initSelectedRectangle(MouseEvent e) {
			_rectangle.setLocation(_pointer);
			_rectangle.setSize(0, 0);
		}

		private void increaseSelectedRectangle(MouseEvent e) {
			_rectangle.setSize(e.getX() + window.x - _rectangle.x, e.getY() + window.y - _rectangle.y);
		}

		public final boolean isLeftButton(final MouseEvent e) {
			return (e.getModifiers() & InputEvent.BUTTON1_MASK) != 0;
		}

		public final boolean isRightButton(final MouseEvent e) {
			return (e.getModifiers() & InputEvent.BUTTON3_MASK) != 0;
		}

	}

	public void cleanSelectedFloorArea() {
		selectedRectangles.clear();
		flushMap();
	}

	public void cleanSelectedItem() {
	}

	public void cleanSelectRectangle() {
		_rectangle.setSize(0, 0);
		flushMap();
	}

	public SmallMapComponent getSmallMapComponent() {
		return new SmallMapComponent(this, new SmallMapListener() {
			@Override
			public void onMousePressed(int x, int y) {
				setMap(x, y);
			}
		});
	}

	public void moveMap(int ox, int oy) {
		window.translate(ox, oy);
		callScreenAreaChangeListener();
		flushMap();
	}

	public void setMap(int x, int y) {
		window.setLocation(x - getWidth() / 2, y - getHeight() / 2);
		callScreenAreaChangeListener();
		flushMap();
	}

	public void setPointerState(int state) {
		cleanSelectedFloorArea();
		cleanSelectedItem();
		this.pointerState = state;
		flushMap();
	}

	// private void findItemLocation(Item item) {
	// if (item != null) {
	// setPointerState(POINTER_STATE_EDIT_ITEM);
	// itemElementPack = new ItemElementPack(item);
	// }
	// }

	private final boolean isEditFloor() {
		return pointerState == POINTER_STATE_EDIT_FLOOR;
	}

	private final boolean isEditItem() {
		return pointerState == POINTER_STATE_EDIT_ITEM;
	}

	private void callScreenAreaChangeListener() {
	}

	private void callMapElemenetChangeListener() {
	}

	public final boolean isKeyDown(int keyCode) {
		return MapComponent.this.keyCode == keyCode;
	}

	public final boolean isControlKeyDown() {
		return ((keyModifiersEx & KeyEvent.CTRL_DOWN_MASK) != 0);
	}

	public final boolean isCallSaveDown() {
		return ((keyModifiersEx & KeyEvent.CTRL_DOWN_MASK) != 0) && keyCode == KeyEvent.VK_S;
	}

	public final boolean isCallCopyDown() {
		return ((keyModifiersEx & KeyEvent.CTRL_DOWN_MASK) != 0) && keyCode == KeyEvent.VK_V;
	}

	public final boolean isShiftKeyDown() {
		return ((keyModifiersEx & KeyEvent.SHIFT_DOWN_MASK) != 0);
	}

}
